package com.firexxx.vp.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;


/**
 * 文件操作
 */
public class FileUtil {
    private static final String prompt = "desc=FileOperation----";
    private final static Logger logger = LoggerFactory.getLogger(FileUtil.class);

    /**
     * 写数据到文件中，覆盖
     *
     * @param fileName
     * @param content
     * @return
     * @throws IOException
     */
    public synchronized static String writeToFile(String fileName, String content) throws IOException {

        File file = new File(fileName);

        //目录不存在 则创建
        if (!file.getParentFile().exists()) {
            boolean mkdir = file.getParentFile().mkdirs();
            if (!mkdir) {
                throw new RuntimeException("创建目标文件所在目录失败！");
            }
        }

        if (!file.exists()) {
            file.createNewFile();
        }

        FileWriter fileWriter = new FileWriter(file.getAbsoluteFile());

        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);

        bufferedWriter.write(content);

        bufferedWriter.close();
        fileWriter.close();

        return "success";

    }

    /**
     * 写数据到文件中，覆盖
     *
     * @param filename
     * @param bytes
     * @return
     * @throws IOException
     */
    public synchronized static boolean writeToFile(String filename, byte[] bytes) throws IOException {
        if ((filename == null) || (filename.length() == 0)) {
            logger.error(prompt + "writeToFile:输入参数错误,文件名不存在");

            return false;
        }

        if ((bytes == null) || (bytes.length == 0)) {
            logger.error(prompt + "writeToFile:输入参数错误,字节流不存在");

            return false;
        }

        File file = new File(filename);
        //目录不存在 则创建
        if (!file.getParentFile().exists()) {
            boolean mkdir = file.getParentFile().mkdirs();
            if (!mkdir) {
                throw new RuntimeException("创建目标文件所在目录失败！");
            }
        }

        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(filename);
            fos.write(bytes);

            return true;
        } catch (IOException ioe) {
            logger.error(prompt + "writeToFile:未知异常" + ioe);
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    logger.error(prompt + "writeToFile:关闭流出现异常" + e);
                }
            }
        }

        return false;
    }

    public static File[] getDirFiles(String dir) {
        File dirFile = new File(dir);

        return dirFile.listFiles();
    }

    /**
     * 读取文件
     * @param filename
     */
    public static byte[] readAllBytes(String filename) throws IOException {
        try (FileInputStream fis = new FileInputStream(new File(filename));ByteArrayOutputStream baos = new ByteArrayOutputStream(1024)) {
            byte[] b = new byte[1000];
            int n;
            while ((n = fis.read(b)) != -1) {
                baos.write(b, 0, n);
            }

            return baos.toByteArray();
        }
    }

    /**
     * 读取文件
     * @param file
     */
    public static byte[] readAllBytes(File file) throws IOException {
        try (FileInputStream fis = new FileInputStream(file);ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);) {
            byte[] b = new byte[1000];
            int n;
            while ((n = fis.read(b)) != -1) {
                baos.write(b, 0, n);
            }

            return baos.toByteArray();
        }
    }

    /**
     * 写数据到文件中，追加,文件不存在时，自动创建
     *
     * @param file
     * @param conent
     */
    public static void appendDataToFile(String file, String conent) {


        BufferedWriter out = null;
        try {
            //out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));     

            //new FileOutputStream(file,true)  true:表示以追加的形式放入数据

            OutputStreamWriter outputStreamWriter =
                    new OutputStreamWriter(new FileOutputStream(file, true), "utf-8");

            out = new BufferedWriter(outputStreamWriter);

            //System.out.println(conent);

            //out.write(conent);
            out.append(conent);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 以行为单位读取文件，常用于读面向行的格式化文件件,返回一个list数组
     *
     * @param fileName
     */
    public static List<String> readFileByLines(String fileName) {

        List<String> movieName = new ArrayList<String>();
        //File file = new File(fileName);

        BufferedReader bufferedReader = null;

        try {
            //bufferedReader = new BufferedReader(new FileReader(file));
            FileInputStream fileInputStream = new FileInputStream(fileName);

            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");

            bufferedReader = new BufferedReader(inputStreamReader);


            String tempString = null;
            int line = 0;

            while ((tempString = bufferedReader.readLine()) != null) {

                //System.out.println(tempString);

                line++;
                movieName.add(tempString);
            }

            bufferedReader.close();

            //System.out.println("个数为: "+line);


        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {

            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }

        return movieName;

    }

    /**
     * 以行为单位读取文件，常用于读面向行的格式化文件件,返回一个list数组
     *
     * @param file
     */
    public static List<String> readFileByLines(File file) {

        List<String> movieName = new ArrayList<String>();
        //File file = new File(fileName);

        BufferedReader bufferedReader = null;

        try {
            //bufferedReader = new BufferedReader(new FileReader(file));
            FileInputStream fileInputStream = new FileInputStream(file);

            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");

            bufferedReader = new BufferedReader(inputStreamReader);


            String tempString = null;
            int line = 0;

            while ((tempString = bufferedReader.readLine()) != null) {

                //System.out.println(tempString);

                line++;
                movieName.add(tempString);
            }

            bufferedReader.close();

            //System.out.println("个数为: "+line);


        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {

            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }

        return movieName;

    }


    /**
     * 以行为单位读取文件，需要传入编码格式,返回一个list数组
     * UTF-8
     *
     * @param fileName
     * @param format
     */
    public static List<String> readFormatedFileByLines(String fileName, String format) {
        List<String> rowList = new ArrayList<String>();
        BufferedReader bufferedReader = null;
        FileInputStream fileInputStream = null;
        InputStreamReader inputStreamReader = null;
        try {
            fileInputStream = new FileInputStream(fileName);
            inputStreamReader = new InputStreamReader(fileInputStream, format);
            bufferedReader = new BufferedReader(inputStreamReader);
            String rowString = null;
            while ((rowString = bufferedReader.readLine()) != null) {
                rowList.add(rowString);
            }
            bufferedReader.close();
        } catch (FileNotFoundException e) {
            logger.error("读取文件失败", e);
        } catch (IOException e) {
            logger.error("读取文件失败", e);
        } finally {
            try {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
                if (inputStreamReader != null) {
                    inputStreamReader.close();
                }
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                logger.error("关闭流失败", e);
            }
        }
        return rowList;
    }

    /**
     * 以行为单位读取文件，返回包含整个文件内容的一个字符串
     *
     * @param fileName
     * @param flag
     * @return
     */
    public static String readFileByLines(String fileName, String flag) {

        String result = "";

        List<String> movieName = new ArrayList<String>();
        //File file = new File(fileName);

        BufferedReader bufferedReader = null;

        try {
            //bufferedReader = new BufferedReader(new FileReader(file));
            FileInputStream fileInputStream = new FileInputStream(fileName);

            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "utf-8");

            bufferedReader = new BufferedReader(inputStreamReader);


            String tempString = null;
            int line = 0;

            while ((tempString = bufferedReader.readLine()) != null) {

                //System.out.println("================当前读取行数: "+line);

                line++;

                result = result + tempString;

                movieName.add(tempString);
            }

            bufferedReader.close();

            //System.out.println("总行数: "+line);


        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {

            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }

        return result;

    }


    /**
     * 以行为单位，读取河北电信的数据，数据比较特殊，数据格式为GB2312
     *
     * @param fileName
     * @return
     */
    public static List<String> ReadFileByLinesForHeBeiData(String fileName, String codeFormat) {

        List<String> movieName = new ArrayList<String>();
        //File file = new File(fileName);

        int count = 1;

        BufferedReader bufferedReader = null;

        try {
            //bufferedReader = new BufferedReader(new FileReader(file));
            FileInputStream fileInputStream = new FileInputStream(fileName);

            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, codeFormat);

            bufferedReader = new BufferedReader(inputStreamReader);


            String tempString = null;
            int line = 0;
            String lineData = null;

            while ((tempString = bufferedReader.readLine()) != null) {

                //System.out.println(tempString);
                String[] strArr = tempString.split("\\t");
                String firstDataOfStrArr = strArr[0];

                count++;
                if (count >= 500) {
                    //break;
                }

                //一行数据如果不以一串数字开头，则说明是是前一行的数据，进行拼接
                //数字没有出现2位或者2位以上的数字，或者有中文，则该行数据是前一行数据
                if (movieName.size() >= 2) {
                    if ((Pattern.compile("[\\u4e00-\\u9fa5]", Pattern.CASE_INSENSITIVE).matcher(firstDataOfStrArr).find())
                            || (Pattern.compile("[A-Za-z]", Pattern.CASE_INSENSITIVE).matcher(firstDataOfStrArr).find())
                            || !(Pattern.compile("[0-9]{2,6}", Pattern.CASE_INSENSITIVE).matcher(firstDataOfStrArr).find())) {

                        //取出前一行数据
                        String beforeLineData = movieName.get(movieName.size() - 1);

                        if (count >= 380) {

//							System.out.println("firstDataOfStrArr: "+firstDataOfStrArr);
//							System.out.println("前一行数据: \n"+beforeLineData+"\n");
                        }


                        lineData = beforeLineData + tempString;
                        //保存
                        //movieName.add(movieName.size()-1, lineData);  //这样不行

                        movieName.set(movieName.size() - 1, lineData);

                        line++;

                    } else {
                        line++;
                        movieName.add(tempString);
                    }

                } else {
                    line++;
                    movieName.add(tempString);

                }


            }

            bufferedReader.close();

            System.out.println("总行数: " + line);


        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {

            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }

        return movieName;

    }


    /**
     * 以行为单位，广东广电，数据比较特殊，数据格式为utf-8
     *
     * @param fileName
     * @return
     */
    public static List<String> ReadFileByLinesForGuangDongData(String fileName, String codeFormat) {
        List<String> oneLineDataList = new ArrayList<String>();
        BufferedReader bufferedReader = null;
        try {
            FileInputStream fileInputStream = new FileInputStream(fileName);
            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, codeFormat);
            bufferedReader = new BufferedReader(inputStreamReader);
            String tempString = null;
            int line = 0;
            String lineData = null;
            while ((tempString = bufferedReader.readLine()) != null) {
                String[] strArr = tempString.split("\",\"");
                String firstDataOfStrArr = strArr[0];
                //一行数据如果不以一串数字开头，则说明是是前一行的数据，进行拼接
                //数字没有出现2位或者2位以上的数字，或者有中文，则该行数据是前一行数据
                if (firstDataOfStrArr != null && !firstDataOfStrArr.equals("")) {
                    if (oneLineDataList.size() >= 2) {
                        if ((Pattern.compile("[\\u4e00-\\u9fa5]", Pattern.CASE_INSENSITIVE).matcher(firstDataOfStrArr).find())
                                || !(Pattern.compile("[0-9]{2,6}", Pattern.CASE_INSENSITIVE).matcher(firstDataOfStrArr).find())) {

                            //取出前一行数据
                            String beforeLineData = oneLineDataList.get(oneLineDataList.size() - 1);
                            lineData = beforeLineData + tempString;
                            //保存
                            //movieName.add(movieName.size()-1, lineData);  //这样不行
                            oneLineDataList.set(oneLineDataList.size() - 1, lineData);
                            line++;
                        } else {
                            line++;
                            oneLineDataList.add(tempString);
                        }
                    } else {
                        line++;
                        oneLineDataList.add(tempString);
                    }
                }
            }
            bufferedReader.close();
            System.out.println("总行数: " + line);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        return oneLineDataList;
    }

    /**
     * 删除制定文件夹下所有文件
     *
     * @param folderPath 文件夹的绝对路径
     */
    public static boolean delAllFile(String folderPath) {
        boolean flag = false;
        File file = new File(folderPath);

        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (folderPath.endsWith(File.separator)) {
                temp = new File(folderPath + tempList[i]);
            } else {
                temp = new File(folderPath + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delAllFile(folderPath + "/" + tempList[i]);// 先删除文件夹里面的文件

            }
        }

        return true;

    }


    /**
     * 解压到指定目录
     */
    public void unZipFiles(String zipPath, String descDir) throws IOException {
        unZipFiles(new File(zipPath), descDir);
    }

    /**
     * 解压文件到指定目录
     */
    public void unZipFiles(File zipFile, String descDir) throws IOException {
        File pathFile = new File(descDir);

        if (!pathFile.exists()) {
            pathFile.mkdirs();

        }

        //解决zip文件中有中文目录或者中文文件
        ZipFile zip = new ZipFile(zipFile, Charset.forName("GBK"));
        for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {
            ZipEntry entry = (ZipEntry) entries.nextElement();
            String zipEntryName = entry.getName();
            InputStream in = zip.getInputStream(entry);
            String outPath = (descDir + zipEntryName).replaceAll("\\*", "/");
            ;

            //判断路径是否存在,不存在则创建文件路径
            File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
            if (!file.exists()) {
                file.mkdirs();
            }

            //判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
            if (new File(outPath).isDirectory()) {
                continue;
            }

            //输出文件路径信息
            System.out.println(outPath);

            OutputStream out = new FileOutputStream(outPath);
            byte[] buf1 = new byte[1024];
            int len;
            while ((len = in.read(buf1)) > 0) {
                out.write(buf1, 0, len);
            }
            in.close();
            out.close();
        }
        System.out.println("******************解压完毕********************");
    }


}
